<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>08-改变Promise实例状态和指定回调函数谁先谁后</title>
</head>

<body>
  <!--  改变Promise实例状态和指定回调函数谁先谁后 ?
      (1) 都有可能, 正常情况下是先指定回调再改变状态, 但也可以先改状态再指定回调 

        ​	先指定回调再改变状态(`异步`):先指定回调 -> 再改变状态 ->改变状态后才进入异步队列执行回调函数

        ​	先改状态再指定回调(`同步`):改变状态 ->指定回调 `并马上执行`回调

      (2) 如何先改状态再`指定`回调?   ->注意:指定并不是执行

        ​	① 在执行器中直接调用 resolve()/reject() ->即,不使用定时器等方法,执行器内直接同步操作 

        ​	② 延迟更长时间才调用 then() 	->即,在`.then()`这个方法外再包一层例如延时器这种方法

      (3) 什么时候才能得到数据? 

        ​	① 如果先指定的回调, 那当状态发生改变时, 回调函数就会调用, 得到数据 

        ​	② 如果先改变的状态, 那当指定回调时, 回调函数就会调用, 得到数据
   -->

  <script>
    // 先指定回调函数再改变状态（常用）
    new Promise((resolve, reject) => {
      setTimeout(() => {
        //因为改变状态是异步的，整个异步回调被放入 宏队列 中，执行此处时，回调函数是在Promise实例身上
        resolve('成功的value11');
      }, 1000);
    }).then(  //执行到这行代码时，promise状态没有改变，不知道是成功还是失败，所以回调函数被放到Promise实例身上，而不是微队列中
      (value) => { console.log('成功的value：' + value); },
      (reason) => { console.log('失败原因：' + reason); }
    );

    //先改变状态，在指定回调函数
    const promise = new Promise((resolve, reject) => {
      resolve('成功的value22');   //改变状态是同步的，先执行
    })
    setTimeout(() => {
      //异步的指定回调函数，后执行，此时状态已经改变等待调用回调，
      //  回调函数就不会放到Promise实例身上，而是出了引擎的callback栈之后立即被调用
      promise.then(
        (value) => { console.log('成功的value：' + value); },
        (reason) => { console.log('失败原因：' + reason); }
      )
    }, 1000);
  </script>
</body>

</html>